import logging
#~ import commands
import socket

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

# -*- coding: utf8 -*-
from scapy.all import *

def port_scan(dst_ip, port_range):
    open_ports = []
    for i in port_range:
        p = IP(dst = dst_ip)/TCP(dport = i, flags = "S")
        response, unans = sr(p, retry=1, timeout = 30, verbose = 1)
        
        if response == None or len(response) == 0:
            print "el puerto "+ str(i) + " esta filtrado"

        else:
            sent, rcvd = response[0]
            
            example = TCP()
            example.flags = "SA"
            example2 = TCP()
            example2.flags = "RA"
            if  rcvd.getlayer(TCP).flags == example.flags:
                open_ports.append(i)
                print "el puerto "+ str(i) + " esta abierto"
            elif rcvd.getlayer(TCP).flags == example2.flags:
                print "el puerto "+ str(i) + " esta cerrado"
    return open_ports

def connect_scan(dst_ip, port_range):
    open_ports = []
    for i in port_range:
        
        #~ comienzo con el three way hand shake
        #~ envio un paquete para iniciar la conexion
        p1 = IP(dst = dst_ip)/TCP(dport = i, flags = "S")
        response, unans = sr(p1, retry=1, timeout = 30, verbose = 1)

        
        if response == None or len(response) == 0:
            print "el puerto "+ str(i) + " esta filtrado"	

        else:
            sent, rcvd = response[0]
            
            example = TCP()
            example.flags = "SA"
            
            #~ me fijo si la respuesta es un syn ack 
            if  rcvd.getlayer(TCP).flags == example.flags: 
                #~ envio un paquete yo con ack y el nro de sequencia correspondiente
                print "recibi un syn ack" 
                seq_num = rcvd.getlayer(TCP).seq + 1
                p2 = IP(dst = dst_ip)/TCP(dport = i, ack = seq_num)
                response2, unans2 = sr(p2, retry=1, timeout = 30, verbose = 1)

                if response2 == None or len(response) == 0:
                    print "no hubo respuesta"
                else:
                    
                    print "logre establecer la conexion con el puerto"
                    open_ports.append(i)				
            else:
                print "no recibi un SYN ACK"
    return open_ports


# Ejercicio 2
# Recibe un puerto abierto
def service_discovery(num_port):
    try:
        name = socket.getservbyport(num_port)
        print "El servicio asociado al puerto", num_port, "es:", name
    except:
        print "El puerto", num_port, "no tiene un servicio asociado."

# Ejercicio  3
def banner_grabbing(pag, num_port):    
    s = None
    
    res = socket.getaddrinfo(pag, num_port, 0, 0, socket.SOL_TCP)
    family, socktype, proto, canonname, sock_addr = res[0]
    try:
        s = socket.socket(family, socktype, proto)
        try:
            s.connect(sock_addr)
        except socket.error, msg:
            s.close()
            s = None

    except socket.error, msg:
        s = None

    if s is None:
        print 'could not open socket'
        sys.exit(1)

    s.send("HTTP/1.0\r\nHost: %s\r\n\r\n" % pag)
    data = s.recv(1024)
    
    string = ""
    while len(data):
        string = string + data
        data = s.recv(1024)    

    print "Banner de %s\n\n" % pag
    print string
    
    s.close()	


def main():
	print "Hola, "
	while True:
		cmd = input("ingrese un comando que desea ejecutar")
		if cmd == "port_scan":
			ip = input("ingrese una direccion ip ")
			rango_puertos = input("ingrese una lista con los puertos que desea escanear")
			port_scan(ip, rango_puertos)
		
		elif cmd == "conect_scan":
			ip = input("ingrese una direccion ip ")
			rango_puertos = input("ingrese una lista con los puertos que desea escanear")
			connect_scan(ip, rango_puertos)
		
		elif cmd == "service_discovery":
			puerto = input("ingrese un numero de puerto")
			service_discovery(puerto)
		
		elif cmd == "banner_grabbing":
			host = input("ingrese una pagina")
			puerto = input("ingrese un numero de puerto")
			banner_grabbing(host, puerto)
		
		elif cmd == "exit":
			break
		
		else:
			print cmd
			print "las opciones validas son: port_scan connect_scan service_discovery banner_grabbing y exit" 
main()
